#include "TcpClient.hpp"
#include <unistd.h>
#include "Err.hpp"
#include "Sock.hpp"
#include "Protocol.hpp"

using namespace ns_protocol;

// 使用手册
static void usage(char proc[])
{
    std::cout << proc << "\n\t"
              << "serverIp serverPort" << std::endl;
}

enum
{
    LEFT=1,
    OPER,
    RIGHT
};

Resquest ParseLine(const std::string&line)
{
    std::string left;
    std::string right;
    char op;
    int status=LEFT;
    int i=0;
    while(i<line.size())
    {
        switch(status)
        {
            case LEFT:
                if(isdigit(line[i]))
                    left.push_back(line[i++]);
                else
                    status=OPER;
                break;
            case OPER:
                op=line[i++];
                status=RIGHT;
                break;
            case RIGHT:
                if(isdigit(line[i]))
                    right.push_back(line[i++]);
                
                break;
        }
    }

    Resquest res;
    res._x=atoi(left.c_str());
    res._y=atoi(right.c_str());
    res._op=op;

    return res;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        usage(argv[0]);
        exit(USAGE_ERR);
    }
    // 提取服务器信息
    uint16_t serverPort = atoi(argv[2]);
    std::string serverIp = argv[1];

    // 创建套接字
    Sock sock;
    sock.Socket();
    int n = sock.Connect(serverIp, serverPort);
    if (n != 0)
        exit(CONNECT_ERR);

    while (true)
    {
        std::string line;
        std::cout<<"Enter# ";
        std::getline(std::cin,line);
        Resquest res=ParseLine(line);
        // std::cout << "num1: ";
        // std::cin >> res._x;
        // std::cout << "num2: ";
        // std::cin >> res._y;
        // std::cout << "op: ";
        // std::cin >> res._op;

        //std::cout << "test:" << res._x << " " << res._op << " " << res._y << std::endl;
        // 1.Resquest序列化
        std::string send_string;
        res.Serialize(&send_string);
        //std::cout << "Resquest序列化:" << send_string << std::endl;

        // 2.添加报头
        send_string = AddHeader(send_string);

        //std::cout << "Resquest添加报头后:" << send_string << std::endl;

        // 3.发送数据
        send(sock.Fd(), send_string.c_str(), send_string.size(), 0);

        // 4.接收响应
        int n = 0;
        std::string buffer;

        while (true)
        {
            std::string package;
            n = ReadPackage(sock.Fd(), buffer, &package);
            if (n < 0)
                break;
            else if (n == 0)
                continue;
            else
            {
                //std::cout<<"得到的响应:"<<package<<std::endl;
                package = RemoveHeader(package, n);
                //std::cout<<"去报头后的响应:"<<package<<std::endl;
                Responce resp;
                resp.Deserialize(package);

                std::cout << "result:" << resp._result << " [code:" << resp._code << "]" << std::endl;
                std::cout<<std::endl;
                break;
            }
        }
    }

    sock.Close();

    return 0;
}